from flask import Blueprint, jsonify, request, render_template, session
from utils.auth import login_required
import os
import traceback
from werkzeug.utils import secure_filename
import cv2
import numpy as np
import requests
import json
import hashlib
import time
import base64

# 创建蓝图
translate_bp = Blueprint('translate', __name__)

# 百度翻译 API 配置
BAIDU_API_KEY = 'CiWDibDXJ7yfkagLyXv1FqWp'
BAIDU_SECRET_KEY = 'ymd6MdH6Mi0UIRiPG10aXhy9q33iEgY1'
BAIDU_TOKEN_URL = 'https://aip.baidubce.com/oauth/2.0/token'
BAIDU_TRANSLATE_URL = 'https://aip.baidubce.com/rpc/2.0/mt/texttrans/v1'
BAIDU_PIC_TRANSLATE_URL = 'https://aip.baidubce.com/file/2.0/mt/pictrans/v1'  # 图片翻译接口
BAIDU_SPEECH_TRANSLATE_URL = 'https://aip.baidubce.com/rpc/2.0/mt/v2/speech-translation'
BAIDU_DOC_TRANSLATE_URL = 'https://aip.baidubce.com/rpc/2.0/mt/v2/doc-translation/create'  # 文档翻译接口
BAIDU_DOC_QUERY_URL = 'https://aip.baidubce.com/rpc/2.0/mt/v2/doc-translation/query'  # 文档翻译查询接口

def get_access_token():
    """获取百度 API access token"""
    try:
        params = {
            'grant_type': 'client_credentials',
            'client_id': BAIDU_API_KEY,
            'client_secret': BAIDU_SECRET_KEY
        }
        response = requests.post(BAIDU_TOKEN_URL, params=params)
        result = response.json()
        
        if 'access_token' in result:
            return result['access_token']
        else:
            print(f"获取token失败: {result}")
            return None
            
    except Exception as e:
        print(f"获取token错误: {str(e)}")
        traceback.print_exc()
        return None

def translate_text(text, from_lang='zh', to_lang='en'):
    """使用百度翻译 API 进行翻译"""
    try:
        # 获取 access token
        access_token = get_access_token()
        if not access_token:
            return None
            
        # 准备请求数据
        headers = {
            'Content-Type': 'application/json'
        }
        
        data = {
            'q': text,
            'from': from_lang,
            'to': to_lang
        }
        
        # 发送翻译请求
        url = f"{BAIDU_TRANSLATE_URL}?access_token={access_token}"
        response = requests.post(url, headers=headers, json=data)
        result = response.json()
        
        if 'result' in result and 'trans_result' in result['result']:
            return result['result']['trans_result'][0]['dst']
        else:
            print(f"翻译错误: {result.get('error_msg', '未知错误')}")
            return None
            
    except Exception as e:
        print(f"翻译错误: {str(e)}")
        traceback.print_exc()
        return None

def translate_image(image_path, from_lang='auto', to_lang='en'):
    """使用百度 API 进行图片翻译"""
    try:
        # 获取 access token
        access_token = get_access_token()
        if not access_token:
            return None
            
        # 读取图片文件
        with open(image_path, 'rb') as f:
            image = f.read()
            
        # 准备请求数据
        url = f"{BAIDU_PIC_TRANSLATE_URL}?access_token={access_token}"
        
        # 发送翻译请求
        data = {
            'from': from_lang,
            'to': to_lang,
            'v': '3'  # API 版本
        }
        files = {
            'image': ('image.jpg', image)
        }
        
        response = requests.post(url, data=data, files=files)
        result = response.json()
        
        print("图片翻译返回结果:", result)  # 调试输出
        
        # 处理翻译结果
        if result.get('error_code') == '0' and result.get('error_msg') == 'success':
            data = result.get('data', {})
            if 'sumSrc' in data and 'sumDst' in data:
                # 处理原文和译文中的换行符
                original = data['sumSrc'].replace('\n', ' ').strip()
                translated = data['sumDst'].replace('\n', ' ').strip()
                return {
                    'original': original,
                    'translated': translated
                }
            elif 'content' in data:
                # 如果没有汇总结果，使用 content 中的结果
                original_texts = []
                translated_texts = []
                for item in data['content']:
                    if 'src' in item:
                        text = item['src'].strip()
                        if text:  # 只添加非空文本
                            original_texts.append(text)
                    if 'dst' in item:
                        text = item['dst'].strip()
                        if text:  # 只添加非空文本
                            translated_texts.append(text)
                
                # 使用空格连接文本，而不是换行符
                return {
                    'original': ' '.join(original_texts) if original_texts else '未检测到文字',
                    'translated': ' '.join(translated_texts) if translated_texts else 'No text detected'
                }
            else:
                return {
                    'original': '未检测到文字',
                    'translated': 'No text detected'
                }
        else:
            print(f"图片翻译结果异常: {result}")
            return None
            
    except Exception as e:
        print(f"图片翻译错误: {str(e)}")
        traceback.print_exc()
        return None

def translate_speech(audio_path, from_lang='zh', to_lang='en'):
    """使用百度 API 进行语音翻译"""
    try:
        # 获取 access token
        access_token = get_access_token()
        if not access_token:
            return None
            
        # 读取音频文件
        with open(audio_path, 'rb') as f:
            audio_data = f.read()
            
        # 将音频数据转换为 base64
        audio_base64 = base64.b64encode(audio_data).decode('utf-8')
            
        # 准备请求数据
        headers = {
            'Content-Type': 'application/json'
        }
        
        data = {
            'voice': audio_base64,
            'format': 'pcm',  # 支持更多音频格式
            'from': from_lang,
            'to': to_lang,
            'rate': 16000  # 采样率
        }
        
        # 发送翻译请求
        url = f"{BAIDU_SPEECH_TRANSLATE_URL}?access_token={access_token}"
        response = requests.post(url, headers=headers, json=data)
        result = response.json()
        
        print("语音翻译返回结果:", result)  # 调试输出
        
        if 'error_code' in result:
            print(f"语音翻译错误: {result.get('error_msg', '未知错误')}")
            return None
            
        # 处理翻译结果
        if 'result' in result:
            # 如果是语音翻译结果
            if 'source' in result['result'] and 'target' in result['result']:
                return {
                    'original': result['result']['source'],
                    'translated': result['result']['target']
                }
            # 其他翻译结果
            return {
                'original': result['result'].get('src_text', '未识别到语音'),
                'translated': result['result'].get('dst_text', 'No speech detected')
            }
        else:
            return None
            
    except Exception as e:
        print(f"语音翻译错误: {str(e)}")
        traceback.print_exc()
        return None

def translate_document(file_path, from_lang='zh', to_lang='en'):
    """使用百度 API 进行文档翻译"""
    try:
        # 获取 access token
        access_token = get_access_token()
        if not access_token:
            return None
            
        # 读取文件并转换为 base64
        with open(file_path, 'rb') as f:
            file_content = f.read()
        file_base64 = base64.b64encode(file_content).decode('utf-8')
        
        print(f"文件路径: {file_path}")
        print(f"文件名: {os.path.basename(file_path)}")
        
        # 获取文件扩展名（不带点）
        filename = os.path.basename(file_path)
        if '.' not in filename:
            print("文件没有扩展名")
            return None
            
        file_ext = filename.rsplit('.', 1)[1].lower()
        print(f"文件扩展名: {file_ext}")
        
        # 检查文件格式
        supported_formats = ['pdf', 'doc', 'docx', 'txt']
        # 如果是 docx 格式，需要特殊处理
        if file_ext == 'docx':
            file_ext = 'doc'
            
        if file_ext not in supported_formats:
            print(f"不支持的文件格式: .{file_ext}")
            return None
        
        data = {
            'from': from_lang,
            'to': to_lang,
            'input': {
                'type': 'file',
                'format': file_ext,
                'content': file_base64,
                'name': os.path.basename(file_path)
            },
            'output': {
                'type': ['docx'],  # 统一输出为 docx 格式
                'name': f'translated_{os.path.basename(file_path)}'
            }
        }
        
        # 检查文件大小
        if len(file_base64) > 50 * 1024 * 1024:  # 50MB
            print("文件大小超过限制")
            return None
        
        # 准备请求头
        headers = {
            'Content-Type': 'application/json'
        }
        
        # 发送翻译请求
        url = f"{BAIDU_DOC_TRANSLATE_URL}?access_token={access_token}"
        response = requests.post(url, headers=headers, json=data)
        result = response.json()
        
        print("文档翻译返回结果:", result)  # 调试输出
        
        if 'error_code' in result:
            print(f"文档翻译错误: {result.get('error_msg', '未知错误')}")
            return None
            
        # 获取任务 ID
        task_id = result.get('result', {}).get('id')
        if not task_id:
            return None
            
        # 轮询翻译结果
        max_retries = 30  # 最大重试次数
        retry_interval = 2  # 重试间隔（秒）
        
        for _ in range(max_retries):
            time.sleep(retry_interval)
            
            # 查询翻译状态
            query_url = f"{BAIDU_DOC_QUERY_URL}?access_token={access_token}"
            query_data = {'id': task_id}
            query_response = requests.post(query_url, headers=headers, json=query_data)
            query_result = query_response.json()
            
            print("文档翻译查询结果:", query_result)  # 调试输出
            
            # 检查是否失败
            status = query_result.get('result', {}).get('data', {}).get('status')
            reason = query_result.get('result', {}).get('data', {}).get('reason')
            
            if status == 'Failed':
                print(f"翻译失败，原因: {reason}")
                return None
            
            if query_result.get('result', {}).get('data', {}).get('status') == 'Succeeded':
                # 获取翻译结果
                output_files = query_result['result']['data'].get('output', {}).get('files', [])
                if output_files:
                    file_url = output_files[0].get('url')
                    if file_url:
                        # 直接返回翻译文件的 URL
                        return {
                            'original': os.path.basename(file_path),
                            'translated': output_files[0].get('filename', ''),
                            'translated_url': file_url
                        }
        
        return None
            
    except Exception as e:
        print(f"文档翻译错误: {str(e)}")
        traceback.print_exc()
        return None

@translate_bp.route('/')
@login_required
def index():
    """翻译页面"""
    return render_template('translate/index.html',
                         username=session.get('username'))

@translate_bp.route('/api/translate', methods=['POST'])
@login_required
def translate():
    """翻译接口"""
    try:
        content_type = request.form.get('type', 'text')
        source_lang = request.form.get('source_lang', 'auto')
        target_lang = request.form.get('target_lang', 'en')
        
        if content_type == 'text':
            text = request.form.get('text', '')
            if not text:
                return jsonify({'status': 'error', 'message': '请输入要翻译的文本'})
                
            translated = translate_text(text, source_lang, target_lang)
            if translated:
                return jsonify({
                    'status': 'success',
                    'result': {
                        'original': text,
                        'translated': translated
                    }
                })
            else:
                return jsonify({'status': 'error', 'message': '翻译失败'})
                
        elif content_type == 'image':
            if 'image' not in request.files:
                return jsonify({'status': 'error', 'message': '请选择图片'})
                
            image_file = request.files['image']
            if not image_file:
                return jsonify({'status': 'error', 'message': '无效的图片'})
                
            # 保存并处理图片
            filename = os.path.join('static', 'uploads', 'translate_' + secure_filename(image_file.filename))
            os.makedirs(os.path.dirname(filename), exist_ok=True)
            image_file.save(filename)
            
            try:
                result = translate_image(filename, from_lang=source_lang, to_lang=target_lang)
                if result:
                    return jsonify({
                        'status': 'success',
                        'result': result
                    })
                else:
                    return jsonify({'status': 'error', 'message': '翻译失败'})
            finally:
                # 清理临时文件
                if os.path.exists(filename):
                    os.remove(filename)
                    
        elif content_type == 'audio':
            # 获取音频数据
            audio_data = None
            filename = None
            
            if 'audio' in request.files:  # 文件上传
                audio_file = request.files['audio']
                if audio_file:
                    filename = os.path.join('static', 'uploads', 'translate_' + secure_filename(audio_file.filename))
                    os.makedirs(os.path.dirname(filename), exist_ok=True)
                    audio_file.save(filename)
            elif 'audio_data' in request.form:  # Base64 音频数据
                audio_base64 = request.form['audio_data']
                audio_data = base64.b64decode(audio_base64.split(',')[1])
                filename = os.path.join('static', 'uploads', f'translate_{int(time.time())}.wav')
                os.makedirs(os.path.dirname(filename), exist_ok=True)
                with open(filename, 'wb') as f:
                    f.write(audio_data)
            else:
                return jsonify({'status': 'error', 'message': '未找到音频数据'})
            
            try:
                result = translate_speech(filename, from_lang=source_lang, to_lang=target_lang)
                if result:
                    return jsonify({
                        'status': 'success',
                        'result': result
                    })
                else:
                    return jsonify({'status': 'error', 'message': '翻译失败'})
            finally:
                # 清理临时文件
                if filename and os.path.exists(filename):
                    os.remove(filename)
                    
        elif content_type == 'document':
            if 'document' not in request.files:
                return jsonify({'status': 'error', 'message': '请选择文档'})
                
            document_file = request.files['document']
            if not document_file:
                return jsonify({'status': 'error', 'message': '无效的文档'})
                
            # 获取原始文件名和扩展名
            original_filename = document_file.filename
            if '.' not in original_filename:
                return jsonify({'status': 'error', 'message': '文件必须有扩展名'})
            
            # 分别处理文件名和扩展名
            name_part = os.path.splitext(original_filename)[0]
            ext_part = os.path.splitext(original_filename)[1]
            
            # 安全处理文件名，但保留扩展名
            safe_filename = secure_filename(name_part) + ext_part
            
            # 保存并处理文档
            filename = os.path.join('static', 'uploads', 'translate_' + safe_filename)
            os.makedirs(os.path.dirname(filename), exist_ok=True)
            document_file.save(filename)
            
            try:
                result = translate_document(filename, from_lang=source_lang, to_lang=target_lang)
                if result:
                    return jsonify({
                        'status': 'success',
                        'result': result
                    })
                else:
                    return jsonify({'status': 'error', 'message': '翻译失败'})
            finally:
                # 清理临时文件
                if os.path.exists(filename):
                    os.remove(filename)
                    
        return jsonify({'status': 'error', 'message': '不支持的内容类型'})
        
    except Exception as e:
        print(f"翻译请求错误: {str(e)}")
        traceback.print_exc()
        return jsonify({'status': 'error', 'message': str(e)}) 